package controle.redeNeural;

import static controle.dados.Constants.*;

import java.util.Arrays;
import interfaces.IParametroRedeNeural;
import Matematica.XY;
import controle.dados.PosicaoJogador;

public class RNRetornarMinhaArea extends RNGenerica {

	public static String CAMINHO_RN_RETORNAR = "voltarMinhaArea.nnet";
	public static int NUMERO_ENTRADAS = 5;
	public static int NUMERO_SAIDAS = 6;
	
	public RNRetornarMinhaArea() {
		super(CAMINHO_RN_RETORNAR, NUMERO_ENTRADAS, NUMERO_SAIDAS);
	}

	public XY [] executar(IParametroRedeNeural parametroRedeNeural) {
		ultimaEntrada = parametroRedeNeural;

		PosicaoJogador [] posicoes = parametroRedeNeural.getPosicaoTodosJogadores();
		double [] entradas = new double [NUMERO_ENTRADAS];
		for (int i = 0; i < entradas.length; i++) {
			if(i < posicoes.length)
			{
			    entradas[i] = posicoes[i].getValor();
			}
			else
			{
				entradas[i] = posicoes[posicoes.length-1].getValor();
			}
		}
		perceptron.setInput(entradas);
		perceptron.calculate();
		double [] saida = perceptron.getOutput();
			
		PosicaoJogador posicaoJogadorNossoTime = posicoes[POSICAO_JOGADOR_NOSSO_TIME_RN];
		System.out.println("Selecionou a posição " + MetodosAuxiliares.binaryDoubleToInt(saida) + 
				" para alcançar o refém");
		
		//Descobre a posição do jogador inicial
        int valorPosicaoRelativaX = posicaoJogadorNossoTime.getPosicaoRelativaX();
        
        XY [] saidaXY = new XY[3-valorPosicaoRelativaX];
        
        PosicaoJogador posicaoJogadorAux = new PosicaoJogador(posicaoJogadorNossoTime.getValor());
        
        //Gerando as saidas XY, calcula a partir de uma posição aleatória
        for(int i = valorPosicaoRelativaX; i < saidaXY.length; i++){
           int novoYRelativoBinario = MetodosAuxiliares.binaryDoubleToInt(Arrays.copyOfRange(saida,2*i,2*i+2));
           System.out.println("Nova coluna: " + novoYRelativoBinario);
           //atualiza
           posicaoJogadorAux.setValor((i-1)*4+novoYRelativoBinario);
           saidaXY[i] = posicaoJogadorAux.getPosicaoAbsolutaAleatoria();
        }		
        
        return saidaXY;
	}
	
	@Override
	public void treinarNovamente(){
		if(ultimaEntrada != null){
			PosicaoJogador [] posicoes = ultimaEntrada.getPosicaoTodosJogadores();
			int[] entradas = new int [NUMERO_ENTRADAS];
			for (int i = 0; i < entradas.length; i++) {
				if(i < posicoes.length)
				{
				    entradas[i] = posicoes[i].getValor();
				}
				else
				{
					entradas[i] = posicoes[posicoes.length-1].getValor();
				}
			}
			
			double [] entradasRN = new double[entradas.length];
			
			for(int i = 0; i < entradasRN.length; i++){
				entradasRN[i] = entradas[i];
			}
			
			double [] saida = getSaidaDesejada(entradas[0],Arrays.copyOfRange(entradas, 1, entradas.length));
		}
		
		
	}
	
	private double [] getSaidaDesejada(int posicaoJogadorNossoTime, int [] adversarios){
		double [] saida = new double [6];
		
		for(int i = 0; i < saida.length; i++)
		{
			saida[i] = 0;
		}
	    
		int linhaAtual = (int)Math.abs((posicaoJogadorNossoTime/4) -3);
		int novaPosicaoJogador = posicaoJogadorNossoTime;
		
		while(linhaAtual < 3)
		{
			//Pega a coluna que o jogador deve andar para a próxima coluna
			int novaColuna = MetodosAuxiliares.acharColunaVaziaRetornar(novaPosicaoJogador,adversarios);
			//indicando a coluna para onde o jogador deve ir agora na RN
			double [] colunaSaida = MetodosAuxiliares.toBinaryDouble2(novaColuna);
			saida[linhaAtual*2] = colunaSaida[0];
			saida[linhaAtual*2+1] = colunaSaida[1];
			//incrementa a linha atual
			linhaAtual++;
			novaPosicaoJogador = (Math.abs(linhaAtual-3))*4 + novaColuna;
		}
		
		return saida;		
	}
}